import { buildQiniuUrl, getUploadKey, uploadToQiniu } from '@/services/upload';
import { PlusOutlined } from '@ant-design/icons';
import { Image, message, Space, Upload } from 'antd';
import type { UploadChangeParam } from 'antd/lib/upload/interface';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import VideoPreviewModal, { VideoPreviewModalRef } from './VideoPreviewModal';

interface ImageUploadData {
  [key: string]: any;
  url?: string;
}

interface ImageUploadProps {
  value?: ImageUploadData[];
  maxSize?: number;
  uploadType?: string;
  onChange?: (list: ImageUploadData[]) => void;
  accept?: string;
  readonly?: boolean;
  showPreviewIcon?: string;
  showRemoveIcon?: string;
  max?: number;
  height?: number;
  width?: number;
}

const ServerImageUpload: React.FC<ImageUploadProps> = React.forwardRef((props) => {
  const [messageApi, messageContextHolder] = message.useMessage();
  const maxSize = props?.maxSize || 1024 * 1024 * 10;
  const videoPreviewModalRef = useRef<VideoPreviewModalRef>(null);

  useEffect(() => {
    const handleError = (error: ErrorEvent) => {
      console.error('ServerImageUpload caught error:', error);
      if (error.message.includes("Cannot read properties of undefined (reading 'then')")) {
        console.error(
          'Promise chain broken - this usually means an async function returned undefined',
        );
      }
    };

    window.addEventListener('error', handleError);
    return () => window.removeEventListener('error', handleError);
  }, []);

  const accept = useMemo(() => {
    if (!props.accept) {
      return 'image/*,application/pdf';
    }
    return props.accept;
  }, [props.accept]);

  const isVideo = (fileUrl: any) => {
    if (!fileUrl || typeof fileUrl !== 'string') {
      return false;
    }

    let fileExtension = '';
    try {
      const urlParts = fileUrl.split('?')[0];
      const pathParts = urlParts.split('/');
      const fileName = pathParts[pathParts.length - 1];
      fileExtension = fileName.split('.').pop()?.toLowerCase() || '';
    } catch (error) {
      fileExtension = '';
    }

    const videoExtensions = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv', 'm4v', '3gp', 'ogv'];
    return fileExtension && videoExtensions.includes(fileExtension);
  };

  const isPdf = (fileUrl: any) => {
    if (!fileUrl || typeof fileUrl !== 'string') {
      return false;
    }

    let fileExtension = '';
    try {
      const urlParts = fileUrl.split('?')[0];
      const pathParts = urlParts.split('/');
      const fileName = pathParts[pathParts.length - 1];
      fileExtension = fileName.split('.').pop()?.toLowerCase() || '';
    } catch (error) {
      fileExtension = '';
    }

    return fileExtension === 'pdf';
  };

  // isImage function removed as it's not used

  // getFileType function removed as it's not used

  const canUpload = (file: any) => {
    if (!file) {
      messageApi.error('文件不存在');
      return false;
    }

    if (file.size > maxSize) {
      messageApi.error(`文件大小不能超过 ${(maxSize / 1024 / 1024).toFixed(1)}MB`);
      return false;
    }

    return true;
  };

  const beforeUpload = useCallback(
    (file: any) => {
      if (!canUpload(file)) {
        return false;
      }

      if (!(file instanceof File)) {
        messageApi.error('文件类型无效');
        return false;
      }

      const allowedImageTypes = [
        'image/jpeg',
        'image/jpg',
        'image/png',
        'image/gif',
        'image/webp',
        'image/bmp',
        'image/svg+xml',
      ];
      const allowedVideoTypes = [
        'video/mp4',
        'video/avi',
        'video/mov',
        'video/wmv',
        'video/flv',
        'video/webm',
        'video/mkv',
      ];
      const allowedTypes = [...allowedImageTypes, ...allowedVideoTypes];

      if (file.type && !allowedTypes.includes(file.type)) {
        const errorMsg = `不支持的文件类型: ${file.type}。支持的类型: ${allowedTypes.join(', ')}`;
        messageApi.error(errorMsg);
        return false;
      }

      return file;
    },
    [maxSize, messageApi],
  );

  const debugFileObject = (file: any, context: string) => {
    console.log(`=== Debug File Object (${context}) ===`);
    console.log('File object:', file);
    console.log('File URL:', file.url);
    console.log('File thumbUrl:', file.thumbUrl);
    console.log('File response:', file.response);
    console.log('File response.url:', file.response?.url);
    console.log('File response.data:', file.response?.data);
    console.log('File response.data?.url:', file.response?.data?.url);
    console.log('File name:', file.name);
    console.log('File type:', file.type);
    console.log('File status:', file.status);
    console.log('=====================================');
  };

  const ensureFileStructure = useCallback((fileList: any[]) => {
    if (!fileList || !Array.isArray(fileList)) return [];

    return fileList.map((file) => {
      debugFileObject(file, 'ensureFileStructure input');

      if (file.thumbUrl && file.response && file.url) {
        return file;
      }

      const enhancedFile = {
        ...file,
        url: file.url || file.response?.url || file.response?.data?.url,
        thumbUrl: file.thumbUrl || file.url || file.response?.url || file.response?.data?.url,
        response: file.response || {
          url: file.url || file.response?.url || file.response?.data?.url,
          key:
            (file.url || file.response?.url || file.response?.data?.url) &&
            typeof (file.url || file.response?.url || file.response?.data?.url) === 'string'
              ? (file.url || file.response?.url || file.response?.data?.url).split('/').pop() || ''
              : '',
          hash: file.response?.hash || '',
          fsize: file.size || file.response?.fsize || 0,
          mimeType: file.type || file.response?.mimeType || '',
        },
      };

      debugFileObject(enhancedFile, 'ensureFileStructure output');
      return enhancedFile;
    });
  }, []);

  const customUpload = useCallback(
    async (options: any) => {
      const { file, onProgress, onSuccess, onError } = options;

      try {
        if (!file || !file.name) {
          const errorMsg = '文件信息不完整';
          messageApi.error(errorMsg);
          onError?.(new Error(errorMsg));
          return Promise.resolve();
        }

        onProgress?.({ percent: 10 });

        const timestamp = Date.now();
        const randomStr = Math.random().toString(36).substring(2, 8);
        const date = new Date();
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');

        const fileKey = `${
          props.uploadType || 'default'
        }/${year}${month}${day}/${timestamp}_${randomStr}_${file.name}`;

        onProgress?.({ percent: 30 });

        const uploadKey = await getUploadKey({});
        if (!uploadKey) {
          throw new Error('获取上传凭证失败');
        }

        onProgress?.({ percent: 50 });

        const uploadResult = await uploadToQiniu(file, fileKey, uploadKey);
        if (!uploadResult) {
          throw new Error('上传失败');
        }

        onProgress?.({ percent: 90 });

        const fileUrl = buildQiniuUrl(fileKey);

        const fileInfo = {
          uid: file.uid || `${timestamp}_${randomStr}`,
          name: file.name,
          status: 'done',
          url: fileUrl,
          thumbUrl: fileUrl,
          size: file.size,
          type: file.type,
          response: {
            url: fileUrl,
            key: fileKey,
            hash: uploadResult.hash || '',
            fsize: uploadResult.fsize || file.size,
            mimeType: file.type,
          },
        };

        onProgress?.({ percent: 100 });
        onSuccess?.(fileInfo);

        messageApi.success('上传成功');
      } catch (error: any) {
        console.error('Upload error:', error);
        messageApi.error(`上传失败: ${error.message || '未知错误'}`);
        onError?.(error);
      }
    },
    [props.uploadType, messageApi],
  );

  const handleChange = useCallback(
    (fileInfo: UploadChangeParam) => {
      console.log('handleChange called with:', fileInfo);

      const list = fileInfo.fileList.filter((v: any) => {
        console.log(`File ${v.name} status:`, v.status);

        if (v.status === 'error') {
          console.error(`File ${v.name} upload failed:`, v.error);
          messageApi.error(`文件 ${v.name} 上传失败`);
          return false;
        }

        return true;
      });

      const processedList = ensureFileStructure(list);
      console.log('Processed file list:', processedList);

      if (props.onChange) {
        props.onChange(processedList);
      }
    },
    [props.onChange, ensureFileStructure, messageApi],
  );

  const handleRemove = (file: any) => {
    const currentValue = props.value || [];
    const newValue = currentValue.filter((item) => item.uid !== file.uid);

    if (props.onChange) {
      props.onChange(newValue);
    }

    return true;
  };

  const uploadProps: any = useMemo(() => {
    return {
      name: 'file',
      accept: accept,
      onChange: handleChange,
      onRemove: handleRemove,
      beforeUpload,
      customRequest: customUpload,
      showUploadList: {
        showPreviewIcon: true,
        showRemoveIcon: props.readonly ? false : true,
      },
      multiple: true,
      maxCount: props.max || 999,
    };
  }, [accept, beforeUpload, handleChange, handleRemove, customUpload, props.readonly, props.max]);

  const uploadButton = (
    <div>
      <PlusOutlined />
      <div>上传</div>
    </div>
  );

  return (
    <div>
      {props.readonly && accept.includes('image') ? (
        <Image.PreviewGroup>
          <Space
            style={{
              display: 'flex',
              flexWrap: 'wrap',
              gap: '8px',
            }}
          >
            {props.value?.map((item: any) => {
              if (!item || !item.url) {
                return null;
              }

              return isPdf(item.url) ? (
                <div
                  key={item.url}
                  onClick={() => {
                    window.open(item.url, '_blank');
                  }}
                  style={{
                    cursor: 'pointer',
                    height: props.height || 100,
                    width: props.width || 100,
                    display: 'flex',
                    flexDirection: 'column',
                    alignItems: 'center',
                    justifyContent: 'center',
                    border: '1px solid #d9d9d9',
                    borderRadius: '6px',
                    backgroundColor: '#f5f5f5',
                  }}
                >
                  <div style={{ fontSize: 32, color: '#1890ff', marginBottom: '4px' }}>📄</div>
                  <span style={{ marginTop: 8, fontSize: 12, color: '#666' }}>PDF</span>
                </div>
              ) : isVideo(item.url) ? (
                <div
                  key={item.url}
                  style={{
                    height: props.height || 100,
                    width: props.width || 100,
                    display: 'flex',
                    flexDirection: 'column',
                    alignItems: 'center',
                    justifyContent: 'center',
                    border: '1px solid #d9d9d9',
                    borderRadius: '6px',
                    backgroundColor: '#f5f5f5',
                  }}
                >
                  <div style={{ fontSize: 32, color: '#1890ff', marginBottom: '4px' }}>🎥</div>
                  <span style={{ marginTop: 8, fontSize: 12, color: '#666' }}>VIDEO</span>
                  <video
                    width={Math.min(80, (props.width || 100) - 20)}
                    height={Math.min(60, (props.height || 100) - 40)}
                    src={item.url}
                    controls
                    style={{ marginTop: '4px' }}
                  />
                </div>
              ) : (
                <Image
                  width={props.width || 100}
                  height={props.height || 100}
                  src={item.url}
                  key={item.url}
                />
              );
            })}
          </Space>
        </Image.PreviewGroup>
      ) : (
        <Image.PreviewGroup>
          <Upload
            listType="picture-card"
            {...uploadProps}
            fileList={ensureFileStructure(props.value || [])}
            disabled={props.readonly}
          >
            {(props.value?.length || 0) >= (props.max || 999) ? null : uploadButton}
          </Upload>
        </Image.PreviewGroup>
      )}
      <VideoPreviewModal ref={videoPreviewModalRef} />
      {messageContextHolder}
    </div>
  );
});

ServerImageUpload.displayName = 'ServerImageUpload';

export default ServerImageUpload;
